﻿using ICSharpCode.SharpZipLib.Zip;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NLP.Framework.Common
{
    public class ZipHelper
    {
        /// <summary>
        /// Zip file
        /// </summary>
        /// <param name="streamToZip">The zip file stream,filestream or memorystream</param>
        /// <param name="zipedFile">The ziped file path</param>
        /// <param name="compressionLevel"></param>
        /// <param name="blockSize"></param>
        public static void ZipFile(Stream streamToZip, string zipedFile, int compressionLevel, int blockSize)
        {
            if (streamToZip == null)
            {
                throw new FileNotFoundException("The file stream could not be null.Zipping abordered.");
            }

            FileStream zipFile = File.Create(zipedFile);
            using (ZipOutputStream zipStream = new ZipOutputStream(zipFile))
            {
                ZipEntry zipEntry = new ZipEntry("ZippedFile");
                zipStream.PutNextEntry(zipEntry);
                zipStream.SetLevel(compressionLevel);
                byte[] buffer = new byte[blockSize];
                int size = streamToZip.Read(buffer, 0, buffer.Length);
                zipStream.Write(buffer, 0, size);

                try
                {
                    while (size < streamToZip.Length)
                    {
                        int sizeRead = streamToZip.Read(buffer, 0, buffer.Length);
                        zipStream.Write(buffer, 0, sizeRead);
                        size += sizeRead;
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }

                zipStream.Finish();
            }
        }

        /// <summary>
        /// UnZip file
        /// </summary>
        /// <param name="streamToUnZip">The stream to unzip</param>
        /// <param name="destDirectory">Unzip dest directory</param>
        public static void UnZip(Stream streamToUnZip, string destDirectory)
        {
            using (ZipInputStream stream = new ZipInputStream(streamToUnZip))
            {
                ZipEntry theEntry;
                while ((theEntry = stream.GetNextEntry()) != null)
                {
                    string directoryName = Path.GetDirectoryName(destDirectory);
                    string fileName = Path.GetFileName(theEntry.Name);

                    Directory.CreateDirectory(directoryName);
                    if (!string.IsNullOrEmpty(fileName))
                    {
                        using (FileStream streamWriter = File.Create(destDirectory + theEntry.Name))
                        {
                            int size = 2048;
                            byte[] data = new byte[size];
                            while (true)
                            {
                                size = stream.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
